using System.Collections.Generic;
using System.IO;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

[RequireComponent(typeof(DatasetLoader))]
public class DatasetOptionUIController : MonoBehaviour
{
    [SerializeField] InputActionAsset inputActionAsset;

    [Header("Hint Ui")]
    [SerializeField] Canvas leftHintUI;
    [SerializeField] Canvas rightHintUI;

    [Header("Dataset Option UI")]
    [SerializeField] Canvas datasetUI;

    [Header("Selection Setting UI")]
    [SerializeField] TMP_Dropdown datasetsDropdpwn;

    [Header("Annotation Setting UI")]
    //[SerializeField] Toggle isEditing;
    [SerializeField] List<Button> colorPickers;
    [SerializeField] Color defaultColor;
    [SerializeField] Color annotationColor;

    [Header("Point Size UI")]
    [SerializeField] Slider pointSizeSlider;
    [SerializeField] TMP_Text pointSizeText;

    [Header("Annotation Sphere (in controller)")]
    [SerializeField] GameObject annotationSphere;

    public Color annotationPointColor { get => annotationColor; }
    
    public Color defaultPointColor { get => defaultColor; }

    public bool isAnnotating { get => m_isAnnotating; }
    
    public bool isErasing { get => m_isErasing; }

    public bool isNeither { get => !m_isAnnotating && !m_isErasing; }
    
    public float pointSize { get => m_pointSize; }

    DatasetLoader m_datasetLoader;
    Material m_annotationMaterial;
    bool m_isAnnotating, m_isErasing, m_isOpenDatasetUI;

    List<string> m_datasetPathMap = new List<string>();

    float m_pointSize = 0.3f;

    // Start is called before the first frame update
    void Start()
    {
        m_datasetLoader = GetComponent<DatasetLoader>();

        m_annotationMaterial = annotationSphere.GetComponent<MeshRenderer>().material;

        SetInput();

        #region Color Picker Buttons Setting
        
        foreach (var colPicker in colorPickers)
        {
            colPicker.onClick.AddListener(() =>
            {
                annotationColor = colPicker.GetComponent<Image>().color;
                UseNeitherAnnotationNorEraser();
            });
        }
        // default use the first button color as annotation color
        colorPickers[0].onClick.Invoke();

        #endregion

        #region Annotation and Erase Setting

        m_isAnnotating = false;
        m_isErasing = false;

        #endregion

        #region Datasets Dropdown Setting

        datasetsDropdpwn.onValueChanged.AddListener((int index) =>
        {
            Debug.Log(string.Format("datasetsDropdpwn: {0}", m_datasetPathMap[index]));
            m_datasetLoader.LoadData(m_datasetPathMap[index]);
        });

        List<string> datasetsFileNames = new List<string>();

        DirectoryInfo directoryInfo = new DirectoryInfo(Application.dataPath + "/Datasets");

        datasetsDropdpwn.ClearOptions();

        if (directoryInfo.Exists)
        {
            var fileInfos = directoryInfo.GetFiles("*.csv");
            for (int i = 0; i < fileInfos.Length; i++)
            {
                FileInfo file = fileInfos[i];
                m_datasetPathMap.Add(file.FullName);
                datasetsFileNames.Add(file.Name);
            }

            datasetsDropdpwn.AddOptions(datasetsFileNames);

            // default select dataset 0
            datasetsDropdpwn.onValueChanged.Invoke(0);
        }

        #endregion

        #region Point Size Setting

        pointSizeSlider.onValueChanged.AddListener(value =>
        {
            m_pointSize = value;
            pointSizeText.text = string.Format("{0:0.00}", value);
        });
        pointSizeSlider.onValueChanged.Invoke(pointSizeSlider.value);

        #endregion

        datasetUI.gameObject.SetActive(false);
        leftHintUI.gameObject.SetActive(true);
        rightHintUI.gameObject.SetActive(true);

        m_isOpenDatasetUI = datasetUI.gameObject.activeSelf || leftHintUI.gameObject.activeSelf || rightHintUI.gameObject.activeSelf;

    }

    // Update is called once per frame
    void Update()
    {
        
    }

    void SetInput()
    {
        var actionMap = inputActionAsset.FindActionMap("VisualAnalysis");

        // LeftHandMenu
        var leftHandMenudAction = actionMap.FindAction("LeftHandMenu");
        leftHandMenudAction.started += OnLeftHandMenuPressed;
        leftHandMenudAction.Enable();

        // RightHandMenu
        var rightHandMenudAction = actionMap.FindAction("RightHandMenu");
        rightHandMenudAction.started += OnRightHandMenuPressed;
        rightHandMenudAction.Enable();

        // OnlyRightTrigger
        var onlyRightTriggerAction = actionMap.FindAction("OnlyRightTrigger");
        onlyRightTriggerAction.started += context =>
        {
            if (!m_isOpenDatasetUI && context.ReadValueAsButton() && !m_isErasing)
            {
                m_isAnnotating = true;
                UseAnnotation(annotationColor);
            }
        };
        onlyRightTriggerAction.performed += context =>
        {
            if (!m_isOpenDatasetUI && context.ReadValueAsButton() && !m_isErasing)
            {
                m_isAnnotating = true;
                UseAnnotation(annotationColor);
            }
        };
        onlyRightTriggerAction.canceled += context =>
        {
            m_isAnnotating = false;
            if (!m_isErasing)
            {
                UseNeitherAnnotationNorEraser();
            }
        };
        onlyRightTriggerAction.Enable();

        // OnlyRightHold
        var onlyRightHoldAction = actionMap.FindAction("OnlyRightHold");
        onlyRightHoldAction.started += context =>
        {
            if (!m_isOpenDatasetUI && context.ReadValueAsButton() && !m_isAnnotating)
            {
                m_isErasing = true;
                UseEraser();
            }
        };
        onlyRightHoldAction.performed += context =>
        {
            if (!m_isOpenDatasetUI && context.ReadValueAsButton() && !m_isAnnotating)
            {
                m_isErasing = true;
                UseEraser();
            }
        };
        onlyRightHoldAction.canceled += context =>
        {
            m_isErasing = false;
            if (!m_isAnnotating)
            {
                UseNeitherAnnotationNorEraser();
            }
        };
        onlyRightHoldAction.Enable();

    }

    /// <summary>
    /// set sphere as annotation color
    /// </summary>
    /// <param name="newAnnotationColor">new annotation color</param>
    void UseAnnotation(Color newAnnotationColor)
    {
        annotationColor = newAnnotationColor;
        Color sphereColor = new Color(annotationColor.r, annotationColor.g, annotationColor.b, annotationColor.a * 0.5f);
        m_annotationMaterial.SetColor("_Color", sphereColor);
    }

    void UseEraser()
    {
        Color sphereColor = new Color(defaultColor.r, defaultColor.g, defaultColor.b, defaultColor.a * 0.5f);
        m_annotationMaterial.SetColor("_Color", sphereColor);
    }

    void UseNeitherAnnotationNorEraser()
    {
        m_annotationMaterial.SetColor("_Color", annotationColor);
    }

    void OnLeftHandMenuPressed(InputAction.CallbackContext context)
    {
        datasetUI.gameObject.SetActive(!datasetUI.gameObject.activeSelf);
        m_isOpenDatasetUI = datasetUI.gameObject.activeSelf || leftHintUI.gameObject.activeSelf || rightHintUI.gameObject.activeSelf;
    }

    void OnRightHandMenuPressed(InputAction.CallbackContext context)
    {
        leftHintUI.gameObject.SetActive(!leftHintUI.gameObject.activeSelf);
        rightHintUI.gameObject.SetActive(!rightHintUI.gameObject.activeSelf);
        m_isOpenDatasetUI = datasetUI.gameObject.activeSelf || leftHintUI.gameObject.activeSelf || rightHintUI.gameObject.activeSelf;
    }

}
